package com_.dxy_test_.equals_;


/**
 * @Description String测试
 *
 * Java面试必看的String类和常量池
 * https://baijiahao.baidu.com/s?id=1694462729201489422&wfr=spider&for=pc
 *
 * @Author dangxianyue
 * @Date 2022/11/15 9:40
 */
public class StringEqualsTest {

    //String常量池在Java1.7后是在堆中，存的是引用，而不知对象值
    //"abc"成为字面量，和123数值一样
    //String s = "abc"; sout("s: " + s); //符号引用
    //sout("s: " + "abc");//字面量直接引用
    //类加载，准备后，解析阶段，符号引用替换成直接引用

    public static void main(String[] args) {

        String s1 = "abc";
        String s2 = "abc";
        String s3 = new String("abc");
        String s4 = String.valueOf("abc");
        System.out.println(s1 == s2);//true，s1、s2都是常量池中的引用
        System.out.println(s1 == s3);//false，s3是new创建的对象的地址
        System.out.println(s1 == s4);//true

        String s5 = "123";
        String s6 = String.valueOf(123);
        System.out.println(s5 == s6);//false，调用的是object.toString()

        String s7 = "hello" + "java";//创建3个对象，"hello"一个，"java"一个，"hellojava"一个，字面量会编译优化
        String s8 = "hellojava";
        System.out.println(s7 == s8);//true

        String s9 = "hello";
        String s10 = "java";
        String s11 = s9 + s10;//符号引用，编译期无法优化，+号拼接，先是StringBuffer对象，然后stringBuffer.toString()
        System.out.println(s11 == s8);//false，

        String s12 = "zhangsan";
        String s13 = new String("zhangsan");
        String s14 = s13.intern();
        System.out.println(s12 == s14);//true，intern()，native方法，可以理解为强制使用常量池中的引用，若常量池中没有，则会先创建并把引用放到常量池再返回

    }
}
